package osmconf

import (
	"encoding/json"
	"errors"
	"github.com/wanchain/go-mpc/accounts"
	"github.com/wanchain/go-mpc/accounts/keystore"
	"github.com/wanchain/go-mpc/awskms"
	"github.com/wanchain/go-mpc/common"
	"github.com/wanchain/go-mpc/log"
	"github.com/wanchain/go-mpc/storeman/schnorrmpc"
	"github.com/wanchain/go-mpc/storeman/schnorrmpcbn"
	mpcprotocol "github.com/wanchain/go-mpc/storeman/storemanmpc/protocol"
	"io/ioutil"
)

type KmsInfo struct {
	AKID      string
	SecretKey string
	Region    string
}

func checkJsonFormat(filePath string) (bool, error) {
	keyjson, err := ioutil.ReadFile(filePath)
	if err != nil {
		return false, err
	}

	if json.Valid(keyjson) {
		return true, nil
	}
	return false, nil
}

func GetPrivateShare(ks *keystore.KeyStore,
	address common.Address,
	enableKms bool,
	kmsInfo *KmsInfo,
	password string) (*keystore.Key, int, error) {

	account := accounts.Account{Address: address}
	account, err := ks.Find(account)
	if err != nil {
		log.SyslogErr("find account from keystore fail", "addr", address.String(), "err", err.Error())
		return nil, 0x00, err
	}

	var keyjson []byte

	valid, err := checkJsonFormat(account.URL.Path)
	if err != nil {
		log.SyslogErr("checkJsonFormat error", "err", err.Error())
		return nil, 0x00, err
	}

	// json formt OK
	if valid {
		keyjson, err = ioutil.ReadFile(account.URL.Path)
	} else {
		// try decrpt by kms.
		if len(kmsInfo.AKID) == 0 || len(kmsInfo.SecretKey) == 0 || len(kmsInfo.Region) == 0 {
			err = errors.New("invalid kmsInfo content")
		} else {
			keyjson, err = awskms.DecryptFileToBuffer(account.URL.Path, kmsInfo.AKID, kmsInfo.SecretKey, kmsInfo.Region)
		}
	}

	//if enableKms {
	//	keyjson, err = awskms.DecryptFileToBuffer(account.URL.Path, kmsInfo.AKID, kmsInfo.SecretKey, kmsInfo.Region)
	//} else {
	//	keyjson, err = ioutil.ReadFile(account.URL.Path)
	//}

	if err != nil {
		log.SyslogErr("get account keyjson fail",
			"addr", address.String(),
			"path", account.URL.Path,
			"err", err.Error())

		return nil, 0x01, err
	}

	key, err := keystore.DecryptKey(keyjson, password)
	if err != nil {
		log.SyslogErr("decrypt account keyjson fail",
			"addr", address.String(),
			"path", account.URL.Path,
			"err", err.Error())

		return nil, 0x011, err
	}

	return key, 0x111, nil
}

func GetSmpcer(curveType int) mpcprotocol.SchnorrMPCer {
	var smpcer mpcprotocol.SchnorrMPCer
	switch int(curveType) {
	case mpcprotocol.SK256Curve:
		smpcer = schnorrmpc.NewSkSchnorrMpc()
	case mpcprotocol.BN256Curve:
		smpcer = schnorrmpcbn.NewBnSchnorrMpc()
	default:
		smpcer = schnorrmpc.NewSkSchnorrMpc()
	}
	return smpcer
}
